package controller

import (
	"gitee.com/song-yao-shun/MQH/dto"
	"gitee.com/song-yao-shun/MQH/model"
	"gitee.com/song-yao-shun/MQH/response"
	"gitee.com/song-yao-shun/MQH/respository"
	"gitee.com/song-yao-shun/MQH/vo"
	"github.com/gin-gonic/gin"
	"strconv"
)

type ISceneController interface {
	RestController
}

type SceneController struct {
	SceneRty respository.SceneRepository
}

var sceneTypeMap = map[string]int{
	"unit": 1,
	"integration": 2,
	"system": 3,
}

func (s SceneController) Create(ctx *gin.Context) {
	// 接收参数
	var voRequest vo.CreateSceneRequest
	if err := ctx.ShouldBind(&voRequest); err != nil {
		response.Fail(ctx, nil, "数据验证错误！")
		return
	}

	if voRequest.SceneId != 0 {
		// 获取 path 中的参数
		hscene, err := s.SceneRty.SelectById(voRequest.SceneId)
		if err != nil {
			response.Fail(ctx, nil, "父级测试场景不存在！")
			return
		}
		if sceneTypeMap[hscene.Type] < sceneTypeMap[voRequest.Type]{
			response.Fail(ctx, nil, "低级测试场景不能包含高级测试场景")
			return
		}
	}

	// 创建 page
	result := model.Scene{
		SceneId: 	voRequest.SceneId,
		Name: 		voRequest.Name,
		Type: 		voRequest.Type,
		Desc: 		voRequest.Desc,
	}

	resultId, err := s.SceneRty.Create(result)
	if err != nil {
		response.Fail(ctx, nil, "新建失败！")
		return
	}

	if len(voRequest.Nodes) > 0 {
		var nodes []model.Node
		n := respository.NewNodeRepository()
		for _, node :=  range voRequest.Nodes{
			nc := model.Node{
				FctId: 		node.FctId,
				Name: 		node.Name,
				SceneId: 	resultId,
			}
			nodes = append(nodes,nc)
		}
		result := n.DB.Create(nodes)
		if result.Error != nil{
			response.Fail(ctx, nil, "新增测试场景的节点创建失败！")
			return
		}
	}

	// 返回
	response.Success(ctx, gin.H{"data":resultId}, "新建成功！")
}

func (s SceneController) Update(ctx *gin.Context) {

	// 接收参数
	var voRequest vo.CreateSceneRequest
	if err := ctx.ShouldBind(&voRequest); err != nil {
		response.Fail(ctx, nil, "数据验证错误，请检查提交的内容！")
		return
	}

	// 获取 path 中的参数
	pathId, _ := strconv.Atoi(ctx.Params.ByName("id"))
	updateResult, err := s.SceneRty.SelectById(pathId)
	if err != nil {
		response.Fail(ctx, nil, "测试场景不存在！")
		return
	}

	// 判断变更后的 sceneid 是否有效
	if updateResult.SceneId != voRequest.SceneId{
		hscene, err := s.SceneRty.SelectById(voRequest.SceneId)
		if err != nil {
			response.Fail(ctx, nil, "修改后 的父级 场景 不存在！")
			return
		}
		if voRequest.Type == ""{
			voRequest.Type = updateResult.Type
		}
		if sceneTypeMap[hscene.Type] < sceneTypeMap[voRequest.Type]{
			response.Fail(ctx, nil, "低级测试场景不能包含高级测试场景")
			return
		}
	}

	// 更新 struct
	updateResult.SceneId 	= voRequest.SceneId
	updateResult.Name 		= voRequest.Name
	updateResult.Type 		= voRequest.Type
	updateResult.Desc 		= voRequest.Desc

	result, err := s.SceneRty.Update(*updateResult)
	if err != nil {
		panic(err)
	}

	response.Success(ctx, gin.H{"data":result}, "修改成功。")
}

func (s SceneController) Show(ctx *gin.Context) {

	// 获取 path 中的参数
	pathId, _ := strconv.Atoi(ctx.Params.ByName("id"))
	result := s.SceneRty.SelectFullSceneById(pathId)
	if result.ID == 0 {
		response.Fail(ctx, nil, "测试场景不存在！")
		return
	}

	response.Success(ctx, gin.H{"data":result}, "")
}

func (s SceneController) Delete(ctx *gin.Context) {

	// 获取 path 中的参数
	pathId, _ := strconv.Atoi(ctx.Params.ByName("id"))

	// 判断存在子场景，不允许删除
	// 接收参数
	var voList vo.SceneList
	voList.SceneId = pathId
	_, total := s.SceneRty.List(voList)
	if total > 0 {
		response.Fail(ctx, nil, "存在子场景，不允许删除！")
		return
	}

	if rowsAffected := s.SceneRty.DeleteById(pathId);rowsAffected != 1 {
		response.Fail(ctx, nil, "删除失败，请重试！")
		return
	}

	response.Success(ctx, nil, "删除成功！")
}
func (s SceneController) List(ctx *gin.Context) {

	// 接收参数
	var voList vo.SceneList
	if err := ctx.ShouldBind(&voList); err != nil {
		response.Fail(ctx, nil, "数据验证错误，请检查提交的内容！")
		return
	}

	results, total := s.SceneRty.List(voList)

	if voList.SelectType != ""{
		response.Success(ctx, gin.H{"data":dto.ToSceneDto(results), "total":total}, "查询列表成功。")
		return
	}
	response.Success(ctx, gin.H{"data":results, "total":total}, "查询列表成功。")
}

func NewSceneController() ISceneController{
	return SceneController{SceneRty: respository.NewSceneRepository()}
}

